package com.xxxx.seckill.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wf.captcha.ArithmeticCaptcha;
import com.xxxx.seckill.config.AccessLimit;
import com.xxxx.seckill.exception.CountFail;
import com.xxxx.seckill.pojo.FailMessage;
import com.xxxx.seckill.pojo.Goods;
import com.xxxx.seckill.pojo.Order;
import com.xxxx.seckill.pojo.User;
import com.xxxx.seckill.pojo.dto.GoodsDto;
import com.xxxx.seckill.pojo.dto.MqDto;
import com.xxxx.seckill.pojo.dto.OrderDto;
import com.xxxx.seckill.service.IGoodsService;
import com.xxxx.seckill.service.IOrderService;
import com.xxxx.seckill.vo.RespBean;
import com.xxxx.seckill.vo.RespBeanEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.awt.*;

import static com.xxxx.seckill.pojo.MqNames.EXCHANGE_TOPIC;

/**
 * <p>
 * 秒杀订单表 前端控制器
 * </p>
 *
 * @author zhoubin
 * @since 2022-08-20
 */
@Slf4j
@Controller
@RequestMapping("/seckill")
public class SeckillOrderController {

    @Autowired
    private IOrderService iOrderService;
    @Autowired
    private IGoodsService iGoodsService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 抢购业务
     *
     * @return
     */
    @PostMapping("/doSeckill2")
    public String order2(User user, int goodsId, Model model) {
        if (user == null) {
            return "login";
        }
        //检查用户是否重复购买 或 库存是否充足
        FailMessage failMessage = iOrderService.check(goodsId, user);
        if (!failMessage.isFlag()) {
            model.addAttribute("errmsg", failMessage.getMessage());
            return "secKillFail";
        }
        //查询order表
        Order order = iOrderService.order(user, goodsId);
        //查询商品表
        Goods goods = iGoodsService.getById(goodsId);
        //把数据传给前端
        model.addAttribute("goods", goods);
        model.addAttribute("order", order);
        return "orderDetail";
    }


    /**
     * QPS：73
     * 缓存后QPS : 367
     * 抢购业务
     *
     * @return
     */
    @PostMapping("/{path}/doSeckill")
    @ResponseBody
    public RespBean order(@PathVariable String path, User user, int goodsId) {

        if (user == null) {
            return RespBean.error(RespBeanEnum.NO_USER);
        }
        //检查秒杀地址是否正确
        boolean checkPath = iOrderService.chechPath(user,goodsId,path);
        if (!checkPath){
            return RespBean.error(RespBeanEnum.ERROR_LOCATION);
        }
        //检查用户是否重复购买 或 库存是否充足
        FailMessage failMessage = iOrderService.check(goodsId, user);
        if (!failMessage.isFlag()) {
            return RespBean.error(RespBeanEnum.NO_REPEATED);
        }

        // 异步下单
        rabbitTemplate.convertAndSend(EXCHANGE_TOPIC, "order.order", new MqDto(user, goodsId));
        //查询商品表
        GoodsDto goodsDto = iGoodsService.getDetail(goodsId);
        log.info("秒杀成功。。。。");
        //把数据传给前端
        return RespBean.success(0);
    }


    /**
     * 返回秒杀成功与否信息
     * @param user
     * @param goodsId
     * @return
     */
    @GetMapping("/getResult")
    @ResponseBody
    public RespBean getResult(User user, Long goodsId) {
        // -1 :抢购失败   0 ： 排队中   1： 抢购成功
        if (user == null) {
            return RespBean.error(RespBeanEnum.NO_USER);
        }
        Order order = iOrderService.getOne(new QueryWrapper<Order>()
                .eq("goods_id", goodsId)
                .eq("user_id", user.getId()));
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String isCountIsempty = (String) valueOperations.get("isCountEmpty:"+goodsId);
        if (isCountIsempty.equals("0")) {
            return RespBean.success(-1);
        } else if (!isCountIsempty.equals("0") && order == null) {
            return RespBean.success(0);
        } else {
            return RespBean.success(order.getId());
        }
    }

    /**
     * 生成秒杀地址
     * @param user
     * @param goodsId
     * @return
     */
    @GetMapping("/path")
    @ResponseBody
    @AccessLimit(seconds = 5,maxCount = 5)
    public RespBean getPath(User user ,Long goodsId,Integer captcha){
        boolean captchaFlag = iOrderService.checkCaptcha(user,goodsId,captcha);
        if (!captchaFlag){
            return RespBean.error(RespBeanEnum.ERROR_CAPTCHA);
        }
        String path = iOrderService.createPath(user,goodsId);
        return RespBean.success(path);
    }

    /**
     * 生成验证码
     *
     * @param response
     * @throws Exception
     */
    @RequestMapping("/captcha")
    public void captcha(Long goodsId , User user, HttpServletResponse response) throws Exception {
        // 设置请求头为输出图片类型
        response.setContentType("image/gif");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        // 三个参数分别为宽、高、位数
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(130,32,3);
        // 设置字体
        captcha.setFont(new Font("Verdana", Font.PLAIN, 32));  // 有默认字体，可以不用设置
        redisTemplate.opsForValue().set("captcha:"+user.getId()+":"+goodsId,captcha.text());
//        redisTemplate.opsForValue().set("captcha:"+user.getId()+":"+goodsId,"0");
        // 输出图片流
        captcha.out(response.getOutputStream());
    }

}
